package com.shitou.springai1.admin.filter;

import com.shitou.springai1.admin.entity.dto.CustomUserDetailsDto;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import java.io.IOException;

/**
 * 自定义验证码认证过滤器：处理 /doLogin 的 POST 请求
 */
public class CaptchaAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    // 定义表单参数名（与前端一致）
    public static final String SPRING_SECURITY_FORM_CAPTCHA_KEY = "captcha";
    public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "stuOrTeaId";
    public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "userPass";

    // 验证码参数名
    private String captchaParameter = SPRING_SECURITY_FORM_CAPTCHA_KEY;

    public CaptchaAuthenticationFilter() {
        super();
        // 只处理 POST /doLogin
        this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/doLogin", "POST"));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {
        System.out.println("--- CaptchaAuthenticationFilter.attemptAuthentication() 开始执行 ---");

        if (!request.getMethod().equals("POST")) {
            System.out.println("--- 错误：请求方法不是POST ---");
            throw new AuthenticationServiceException("认证方法不支持：" + request.getMethod());
        }

        String username = obtainUsername(request);
        String password = obtainPassword(request);
        String captcha = obtainCaptcha(request);

        System.out.println("--- 获取到的账号: " + username);
        System.out.println("--- 获取到的密码: " + (password != null ? "******" : "null"));
        System.out.println("--- 获取到的验证码: " + captcha);

        username = (username != null) ? username.trim() : "";
        password = (password != null) ? password : "";
        captcha = (captcha != null) ? captcha.trim() : "";

        HttpSession session = request.getSession();
        String sessionCaptcha = (String) session.getAttribute("captchaCode");
        System.out.println("--- Session ID: " + session.getId());
        System.out.println("--- Session中存储的验证码: " + sessionCaptcha);

        if (sessionCaptcha == null) {
            System.out.println("--- 验证码校验失败：Session中无验证码（可能过期） ---");
            throw new AuthenticationServiceException("验证码已过期，请刷新重试");
        } else if (!captcha.equalsIgnoreCase(sessionCaptcha)) {
            System.out.println("--- 验证码校验失败：输入与Session不一致 ---");
            throw new AuthenticationServiceException("验证码错误");
        }

        session.removeAttribute("captchaCode");
        System.out.println("--- 验证码校验成功！ ---");

        UsernamePasswordAuthenticationToken authRequest =
                new UsernamePasswordAuthenticationToken(username, password);
        setDetails(request, authRequest);

        System.out.println("--- 开始账号密码校验（调用UserServiceImpl） ---");
        Authentication authentication = this.getAuthenticationManager().authenticate(authRequest);
        System.out.println("--- 认证成功！用户: " + authentication.getName() + " ---");

        if (authentication.getPrincipal() instanceof CustomUserDetailsDto) {
            CustomUserDetailsDto customUserDetailsDto = (CustomUserDetailsDto) authentication.getPrincipal();
            System.out.println("得到用户的信息：" + customUserDetailsDto);
            System.out.println("--- 获取到CustomUserDetails，用户ID: " + customUserDetailsDto.getUserDto().getId() + " ---");
        }

        return authentication;
    }

    /**
     * ✅ 修复点：登录成功后，将 SecurityContext 存入 Session。
     * 其他逻辑（比如 successHandler）不做修改。
     */
    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication authResult)
            throws IOException, ServletException {

        System.out.println("=== CaptchaAuthenticationFilter.successfulAuthentication() ===");

        // 创建 SecurityContext 并绑定 Authentication
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(authResult);
        SecurityContextHolder.setContext(context);

        // 手动保存到 HttpSession
        HttpSession session = request.getSession(true);
        session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context);
        System.out.println("✅ 已保存 SecurityContext 到 Session，Session ID：" + session.getId());

        // 调用父类逻辑，继续执行原有成功处理流程（比如 successHandler）
        super.successfulAuthentication(request, response, chain, authResult);
    }

    @Override
    protected String obtainUsername(HttpServletRequest request) {
        return request.getParameter(SPRING_SECURITY_FORM_USERNAME_KEY);
    }

    @Override
    protected String obtainPassword(HttpServletRequest request) {
        return request.getParameter(SPRING_SECURITY_FORM_PASSWORD_KEY);
    }

    protected String obtainCaptcha(HttpServletRequest request) {
        return request.getParameter(captchaParameter);
    }

    public String getCaptchaParameter() {
        return captchaParameter;
    }

    public void setCaptchaParameter(String captchaParameter) {
        this.captchaParameter = captchaParameter;
    }
}
